package com.jwgf.Half485.fxthreadpool;

import com.jwgf.Half485.modbusthreadpool.ModbusUtils;

import org.greenrobot.eventbus.EventBus;

import java.util.HashMap;

/**
 * Created by Jacky on 2017/12/1.
 */

public class FxPLCData {
    private static FxPLCData data = new FxPLCData();

    private HashMap<Integer, Integer> d_registers = new HashMap<Integer, Integer>();

    private FxPLCData() {

    }

    public static FxPLCData getInstance() {
        return data;
    }

    public int getKey(int id, int addr) {
        return (id << 16) | addr;
    }

    public int getKey(FxPLCData.DRegister reg) {
        return (reg.id << 16) | reg.addr;
    }

    public int getValue(int id, int addr) {
        int key = getKey(id, addr);
        Integer value = d_registers.get(key);
        return value == null ? 0 : value;
    }

    public void setValue(int id, int addr, int value) {
        if (value != getValue(id, addr)) {
            d_registers.put(getKey(id, addr), value);
            DRegister dRegister = new DRegister();
            dRegister.fxPLCData = this;
            dRegister.id = id;
            dRegister.addr = addr;
            dRegister.value = value;
            EventBus.getDefault().post(dRegister);
        }
    }

    public void readSucceed(FxData fxData) {
        int id = FxUtils.getRequestId(fxData.send);
        int addr = FxUtils.getRequestAddr(fxData.send);
        int[] data = FxUtils.getReturnData(fxData.recv);
        for (int i = 0; i < data.length; ++i) {
            setValue(id, addr, data[i]);
            ++addr;
        }
        FxResult fxResult = new FxResult();
        fxResult.fxPLCData = this;
        fxResult.id = FxUtils.getRequestId(fxData.send);
        fxResult.cmd = FxUtils.checkCmdType(fxData.send);
        fxResult.addr = FxUtils.getRequestAddr(fxData.send);
        EventBus.getDefault().post(fxResult);
    }

    public void readFailed(FxData fxData) {
        FxResult FxFailed = new FxResult();
        FxFailed.fxPLCData = this;
        FxFailed.id = FxUtils.getRequestId(fxData.send);
        FxFailed.cmd = FxUtils.checkCmdType(fxData.send);
        FxFailed.addr = FxUtils.getRequestAddr(fxData.send);
        EventBus.getDefault().post(FxFailed);
    }

    public void writeSucceed(FxData fxData) {
        int id = FxUtils.getRequestId(fxData.send);
        int addr = FxUtils.getRequestAddr(fxData.send);
        int[] value = FxUtils.getRequestData(fxData.send);
        for (int i = 0; i < value.length; ++i) {
            setValue(id, addr, value[i]);
            ++addr;
        }
        FxResult fxResult = new FxResult();
        fxResult.fxPLCData = this;
        fxResult.id = FxUtils.getRequestId(fxData.send);
        fxResult.cmd = FxUtils.checkCmdType(fxData.send);
        fxResult.addr = FxUtils.getRequestAddr(fxData.send);
        EventBus.getDefault().post(fxResult);
    }

    public void writeFailed(FxData fxData) {
        int id = FxUtils.getRequestId(fxData.send);
        int addr = FxUtils.getRequestAddr(fxData.send);
        int[] value = FxUtils.getRequestData(fxData.send);
        for (int i = 0; i < value.length; ++i) {
            if (value[i] != getValue(id, addr)) {
                DRegister dRegister = new DRegister();
                dRegister.fxPLCData = this;
                dRegister.id = id;
                dRegister.addr = addr;
                dRegister.value = getValue(id, addr);
                EventBus.getDefault().post(dRegister);
            }
            ++addr;
        }
        FxResult fxResult = new FxResult();
        fxResult.fxPLCData = this;
        fxResult.id = FxUtils.getRequestId(fxData.send);
        fxResult.cmd = FxUtils.checkCmdType(fxData.send);
        fxResult.addr = FxUtils.getRequestAddr(fxData.send);
        EventBus.getDefault().post(fxResult);
    }

    public class DRegister {
        public FxPLCData fxPLCData;
        public int id;
        public int addr;
        public int value;
    }

    public static class FxResult {
        public FxPLCData fxPLCData;
        public int id;
        public String cmd;
        public int addr;
    }
}
